﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Threading;

namespace Pascal
{
    public partial class Form1 : Form
    {

        private Size _agentSize = new Size(1,1);
        private Size _anchorSize = new Size(10, 10);
        private Point _anchor1 = new Point(250, 0);
        private Point _anchor2 = new Point(0, 490);
        private Point _anchor3 = new Point(490, 490);
        private int numAgents = 0;
        private int numVertex = 0;
        private ArrayList _agentsList = new ArrayList();
        private ArrayList _vertexList = new ArrayList();
        bool go = false;

        public Form1()
        {
            InitializeComponent();
        }

        private void viewPanel_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;
            //g.FillEllipse(Brushes.Red, new Rectangle(_anchor1, _anchorSize));
            //g.FillEllipse(Brushes.Red, new Rectangle(_anchor2, _anchorSize));
            //g.FillEllipse(Brushes.Red, new Rectangle(_anchor3, _anchorSize));

            //draw agents
            for (int i = 0; i < _agentsList.Count; i++)
            {
                g.FillRectangle(Brushes.Blue, new Rectangle(((Agent)_agentsList[i]).location, _agentSize));
            }
            //draw verticies
            for (int i = 0; i < _vertexList.Count; i++)
            {
                g.FillEllipse(Brushes.Red, new Rectangle((Point)(_vertexList[i]), _anchorSize));
            }


        }

        private void setupButton_Click(object sender, EventArgs e)
        {
           
        }

        private void agentComboBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            numAgents = (agentComboBox.SelectedIndex + 1) * 5000;
        }

        private void goButton_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(runFractal);
            t.Start();
            MessageBox.Show("running...");
        }

        private void timer1_Tick(object sender, EventArgs e)
        {

        }
        private void vertexBox_SelectedIndexChanged(object sender, EventArgs e)
        {
            numVertex = vertexBox.SelectedIndex + 1;
            setVert();
            viewPanel.Invalidate();
        }
        public void runFractal()
        {
            Random myRandom = new Random();
            Agent newAgent, oldAgent;
            go = !go;
            _agentsList.Clear();
            if (numAgents < 1) MessageBox.Show("Please Select Number of Agents From the Dropdown Menu.");
            else
            {
                newAgent = oldAgent = new Agent(new Point(myRandom.Next(viewPanel.Size.Width), myRandom.Next(viewPanel.Size.Height)), _vertexList);
                this.viewPanel.Invalidate();
                while (go)
                {
                    //for (int i = 0; i < numAgents; i++)
                    //{
                        newAgent = new Agent(oldAgent.location, _vertexList);
                        _agentsList.Add(newAgent);
                        oldAgent = newAgent;
                    //}
                }
            }

        }
        private void drawPoint()
        {
            Random myRand = new Random();
            Point myPoint = new Point(myRand.Next(viewPanel.Width), myRand.Next(viewPanel.Height));
            Point vertPoint = (Point)(_vertexList.ToArray()[myRand.Next(_vertexList.Count)]);

            


        }
        private void fractal(Point vert, Point start)
        {

        }
        //checks to see whether or not the agent is inside the area contained by the given three points.
        //public bool isInside(Point A, Point B, Point C)
        //{
        //    // first we create three vectors for two sides of the triangle and the agents position in relation to point A
        //    Single[] side0 = { C.X - A.X, C.Y - A.Y },
        //        side1 = { B.X - A.X, B.Y - A.Y },
        //        side2 = { _location.X - A.X, _location.Y - A.Y };
        //    DenseVector v0 = new DenseVector(side0),
        //        v1 = new DenseVector(side1),
        //        v2 = new DenseVector(side2);
        //    //now we compute their dot products
        //    Single dot00 = v0.DotProduct(v0),
        //        dot01 = v0.DotProduct(v1),
        //        dot02 = v0.DotProduct(v2),
        //        dot11 = v1.DotProduct(v1),
        //        dot12 = v1.DotProduct(v2);
        //    // Compute barycentric coordinates
        //    Single invDenom = 1 / (dot00 * dot11 - dot01 * dot01),
        //        u = (dot11 * dot02 - dot01 * dot12) * invDenom,
        //        v = (dot00 * dot12 - dot01 * dot02) * invDenom;

        //    // Check if point is in triangle
        //    return (u >= 0) && (v >= 0) && (u + v < 1);
        //}
        private void setVert()
        {
            _vertexList.Clear();
            Point p;
            int degree = 360 / numVertex,
                scalar = viewPanel.Size.Width / 2;
            double conversion = Math.PI / 180;
            double angle, x, y;
            for (int i = 1; i <= numVertex; i++)
            {
                angle = conversion * i * degree;
                x = Math.Cos(angle);
                y = Math.Sin(angle);
                p = new Point();
                p.X = scalar + (int)Math.Round(scalar * x)-8;
                p.Y = scalar + (int)Math.Round(scalar * y)-8;
                _vertexList.Add(p);
            }       
        }
        
    }
}
